<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../leader-line-master/leader-line-master/leader-line.min.js"></script>

<!--    <script src="./anim-event.esm.js"></script>-->
    <script>
        /* ================================================
        DON'T MANUALLY EDIT THIS FILE
================================================ */

        /*
         * AnimEvent
         * https://github.com/anseki/anim-event
         *
         * Copyright (c) 2018 anseki
         * Licensed under the MIT license.
         */

        var MSPF = 1000 / 60,
            // ms/frame (FPS: 60)
            KEEP_LOOP = 500,


            /**
             * @typedef {Object} task
             * @property {Event} event
             * @property {function} listener
             */

            /** @type {task[]} */
            tasks = [];

        var requestAnim = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
                return setTimeout(callback, MSPF);
            },
            cancelAnim = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame || function (requestID) {
                return clearTimeout(requestID);
            };

        var lastFrameTime = Date.now(),
            requestID = void 0;

        function step() {
            var called = void 0,
                next = void 0;

            if (requestID) {
                cancelAnim.call(window, requestID);
                requestID = null;
            }

            tasks.forEach(function (task) {
                var event = void 0;
                if (event = task.event) {
                    task.event = null; // Clear it before `task.listener()` because that might fire another event.
                    task.listener(event);
                    called = true;
                }
            });

            if (called) {
                lastFrameTime = Date.now();
                next = true;
            } else if (Date.now() - lastFrameTime < KEEP_LOOP) {
                // Go on for a while
                next = true;
            }
            if (next) {
                requestID = requestAnim.call(window, step);
            }
        }

        function indexOfTasks(listener) {
            var index = -1;
            tasks.some(function (task, i) {
                if (task.listener === listener) {
                    index = i;
                    return true;
                }
                return false;
            });
            return index;
        }

        var AnimEvent = {
            /**
             * @param {function} listener - An event listener.
             * @returns {(function|null)} A wrapped event listener.
             */
            add: function add(listener) {
                var task = void 0;
                if (indexOfTasks(listener) === -1) {
                    tasks.push(task = { listener: listener });
                    return function (event) {
                        task.event = event;
                        if (!requestID) {
                            step();
                        }
                    };
                }
                return null;
            },
            remove: function remove(listener) {
                var iRemove = void 0;
                if ((iRemove = indexOfTasks(listener)) > -1) {
                    tasks.splice(iRemove, 1);
                    if (!tasks.length && requestID) {
                        cancelAnim.call(window, requestID);
                        requestID = null;
                    }
                }
            }
        };
    </script>
    <style>
        .target {
            display: inline-block;
            background-color: #9ee7ea;
            padding: 12px;
        }
        .box{
            width: 200px;
            height: 200px;
        }
        #start {}

        /*#end {*/
        /*    float: right;*/
        /*    margin-top: 200px;*/
        /*}*/

    </style>
</head>
<body>
<div class="box">
    <div id="start" class="target" >start</div>
    <div id="end" class="target">end</div>
    <div id="start2" class="target" >start2</div>
    <div id="end2" class="target">end2</div>
</div>

<script>
    // new LeaderLine(
    //     document.getElementById('start'),
    //     document.getElementById('end')
    // );

    var startEle = document.getElementById('start');
    var endEle = document.getElementById('end');

    var startEle2 = document.getElementById('start2');
    var endEle2 = document.getElementById('end2');


    function getTop(e) {
        var offset = e.offsetTop;
        if (e.offsetParent != null) offset += getTop(e.offsetParent);
        return offset;
    }

    function getLeft(e) {
        var offset = e.offsetLeft;
        if (e.offsetParent != null) offset += getLeft(e.offsetParent);
        return offset;
    }
    console.log(getTop(startEle),getLeft(startEle))
    startEle.style.position="absolute"
    endEle.style.position="absolute"
    endEle.style.top=getTop(startEle)+startEle.clientHeight+2+"px"
    endEle.style.left=getLeft(startEle)+180+"px"


    startEle2.style.position="absolute"
    startEle2.style.left=startEle.style.left
    startEle2.style.top=endEle.style.top


    endEle2.style.position="absolute"
    endEle2.style.left=endEle.style.left
    endEle2.style.top=startEle.style.top


    endEle.onmousedown=function (event) {
        //endEle.setPointerCapture(1);//捕获点击事件到自己身上，避免全选时其他元素被波及
        (endEle.setCapture && endEle.setCapture())||(endEle.setPointerCapture && endEle.setPointerCapture(1))
        //点上后，计算鼠标跟div的相对位置差
        event=event||window.event;
        var mx=event.clientX;
        var my=event.clientY;
        var dx=endEle.offsetLeft;
        var dy=endEle.offsetTop;
        var cx=mx-dx;
        var cy=my-dy;
        //定一个全局鼠标移动事件
        document.onmousemove=function(event){
            event=event||window.event;
            //获取鼠标位置
            var mx=event.clientX;
            var my=event.clientY;
            //算出div顶点应该出现的位置
            var dx=mx-cx;
            var dy=my-cy;
            //重新定义div的位置
            endEle.style.left=dx+"px";
            endEle.style.top=dy+"px";
            leader_line.position();
            //定一个全局鼠标抬起事件，防止点上上层下层不触发。
            document.onmouseup=function () {
                //全局鼠标移动事件为空
                document.onmousemove=null;
                //全局鼠标抬起事件为空
                document.onmouseup=null;
                //endEle.releasePointerCapture(1);//释放捕获鼠标事件，否则会连续捕获下去，以后次次点击都承接到他自己身上了。
                (endEle.releaseCapture && endEle.releaseCapture() ) ||(endEle.releasePointerCapture && endEle.releasePointerCapture(1) )
            }
        }
        return false//取消拖拽的搜索默认行为
    }
    //
    // var leader_line = new LeaderLine(
    //     startEle,
    //     endEle,
    //     {
    //         dash: true,
    //     }
    // );

    // var leader_line = new LeaderLine(
    //     startEle,
    //     endEle,
    //     {
    //         startPlugColor: '#ff3792', // 渐变色开始色
    //         endPlugColor: '#fff386',// 渐变色结束色
    //         gradient: true, // 使用渐变色
    //         dash: { // 虚线样式
    //             animation: true,// 让线条滚动起来
    //         }
    //     }
    // );

    var leader_line = new LeaderLine(
        startEle,
        endEle, {
            startPlugColor: '#ff3792', // 渐变色开始色#ff3792
            endPlugColor: '#fff386', // 渐变色结束色
            gradient: true, // 使用渐变色
            dash: { // 虚线样式
                animation: true, // 让线条滚动起来
            },
            hide: true,
            // color: 'green',
            size: 4,
            // startPlug: 'square', //手指
            // endPlug: 'hand' //手指
        },
    );
    /** 显示效果
     *  draw 从起点到终点绘制线条
     *  fade 淡入淡出
     *  none 无效果，即直接显示
     */
    var showEffectName = 'draw';
    // 动画参数
    var animOptions = {
        duration: 1000, //持续时长
        timing: 'ease-in', // 动画函数
    }
    leader_line.show(showEffectName, animOptions)
    //leader_line.hide(showEffectName,animOptions)
    //window.addEventListener('scroll', AnimEvent.add(function() {
    //    leader_line.position();
    //}), false);
    var leader_line2 = new LeaderLine(
        startEle2,
        endEle2, {
            startPlugColor: '#ff3792', // 渐变色开始色#ff3792
            endPlugColor: '#fff386', // 渐变色结束色
            gradient: true, // 使用渐变色
            dash: { // 虚线样式
                animation: true, // 让线条滚动起来
            },
            //hide: true,  //true,虚线功能消失了 false虚线出现了  true渐变色消失了 false渐变色出现了 也就是说这个属性控制着这个定义是否生效
            //color: 'orange',  //用这2个就可以实现实线的目的
            //size: 4,   //用这2个就可以实现实线的目的
            // startPlug: 'square', //手指
            // endPlug: 'hand' //手指
        },
    );
    leader_line2.show()

</script>
</body>
</html>